<?php


namespace plugin\agent\app\api\logic;

use app\model\pms\Goods;
use app\model\pms\GoodsTag;
use plugin\coupon\app\model\Coupon;
use plugin\coupon\app\model\CouponGoods;
use support\constants\QueueKey;
use support\constants\RedisKey;
use support\Container;
use support\Log;
use support\Redis;
use support\service\MqClient;
use support\utils\Decimal;
use support\utils\Form;
use support\utils\MsClient;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 使用搜索引擎搜索商品
 * Class SearchController
 * @package app\api\controller
 */
class GoodsSearchLogic extends \app\api\logic\GoodsSearchLogic
{
    protected function formatWith(Form $form, array $with)
    {
        if ($form['is_agent']) {
            $with[] = 'agentgoods';
            $with[] = 'agentgoods.rule';
        }
        return $with;
    }

    protected function formatFilter(Form $form, array $filter)
    {
        $form['is_agent'] && $filter[] = "is_agent=1";
        return $filter;
    }

    public function goodsPage(Form $form)
    {
        $data = parent::goodsPage($form);
        $data['records'] = array_map(function ($v) {
            if (!$v['agentgoods']) {
                return $v;
            }
            if ($v['agentgoods']['type'] === 1) {
                $agent_commission = Decimal::newDecimal($v['max_price'])
                    ->multiply($v['agentgoods']['rule']['one_rate'] ?? 0)
                    ->divide(100)
                    ->getValue();
            } else {
                $agent_commission = Decimal::newDecimal($v['max_price'])
                    ->multiply($v['one_rate'] ?? 0)
                    ->divide(100)
                    ->getValue();
            }

            $v['agent_commission'] = $agent_commission;
            return $v;
        }, $data['records']->toArray());
        return $data;
    }

    static function sync($goodsIds)
    {
        $goodsList = Goods::with(array_merge(Goods::getCateWith(), [
            'brand'
        ]))
            ->where('id', 'in', $goodsIds)
            ->select()
            ->toArray();

        $res = self::goodsSync($goodsList);
        dump("同步商品成功:" . json_encode($goodsIds) . " 返回结果:" . json_encode($res));
        Log::info("同步商品成功:" . json_encode($goodsIds) . " 返回结果:" . json_encode($res));
    }

    /**
     * 商品全量同步
     */
    static function fullSync()
    {
        $goodsList = Goods::with(array_merge(Goods::getCateWith(), [
            'brand'
        ]))
            ->select()
            ->toArray();
        $res = self::goodsSync($goodsList);
        dump($res);
    }

    private static function goodsSync($goodsList)
    {
        $tags = GoodsTag::select()->toArray();
        $tagList = array_column($tags, 'name', 'id');
        $docs = [];
        foreach ($goodsList as $item) {
            $tagsIds = $item['tag_ids'];
            $tags_name = [];
            foreach ($tagsIds as $tag) {
                if ($cur = $tagList[$tag] ?? "") {
                    $tags_name[] = $cur;
                }
            }
            $docs[] = [
                "id" => $item['id'],
                "name" => $item['name'],
                "sub_name" => $item['sub_name'],
                "cate_id1" => $item['cate_id1'],
                "cate_id2" => $item['cate_id2'],
                "cate_id3" => $item['cate_id3'],
                "cate_id1_name" => $item['cate1']['name'] ?? "",
                "cate_id2_name" => $item['cate2']['name'] ?? "",
                "cate_id3_name" => $item['cate3']['name'] ?? "",
                "brand_id" => $item['brand_id'],
                "brand_name" => $item['brand']['name'] ?? "",
                "min_price" => $item['min_price'] ?? 0,
                "max_price" => $item['max_price'] ?? 0,
                "sales" => $item['sales'] ?? 0,
                "tag_ids" => $tagsIds,
                "tags_name" => $tags_name,
                "is_show" => $item['is_show'],
                "is_del" => $item['is_del'],
                "is_agent" => $item['is_agent'] ?? 0,
            ];
        }
        $settings = [
            //设置允许查询字段
            'filterableAttributes' => [
                "name",
                "sub_name",
                "cate_id1",
                "cate_id2",
                "cate_id3",
                "brand_id",
                "tag_ids",
                "is_show",
                "is_del",
                "is_agent",
                "id",
            ],
            //设置允许排序的字段
            'sortableAttributes' => [
                'min_price',
                'max_price',
                'sales',
            ],
            //设置排序优先级
            'rankingRules' => [
                'sort', //自定义sort优先
                'words', //关键词相关度优先
                'typo', //错词容忍度
                'proximity',
                'attribute',
                'exactness'
            ]
        ];
        $index = MsClient::client()->index('goods');
        $index->updateSettings($settings);
        return $index->addDocuments($docs);

    }

    /**
     * 增加商品变动 用于定时任务同步搜索商品
     * @param  $goodsIds
     */
    static function addGoodsChange($goodsIds)
    {
        if (!$goodsIds) {
            return;
        }
        $goodsIds = is_array($goodsIds) ? $goodsIds : explode(',', (string)$goodsIds);
        Redis::connection()->pipeline(function ($pipeline) use ($goodsIds) {
            foreach ($goodsIds as $goodsId) {
                $pipeline->sAdd(RedisKey::SEARCH_SYNC, $goodsId);
            }
        });

        Container::get(MqClient::class)->send(QueueKey::GOODS_SYNC, [
            'ids' => $goodsIds,
        ]);
    }

    /**
     * 优惠券条件查询
     * @param $coupon_id
     * @param $filter
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private function couponFilter($coupon_id, $filter)
    {
        $couponModel = new Coupon();
        $coupon = $couponModel->where([
            'id' => $coupon_id,
        ])
            ->field([
                'goods_category_ids',
                'goods_brand_ids',
                'goods_tag_ids',
                'join_goods',
            ])
            ->find();
        if (!$coupon) {
            return $filter;
        }
        if ($coupon['join_goods'] == Coupon::JOIN_GOODS_ALL) {
            if ($coupon['goods_category_ids']) {
                $cateFilter = [];
                foreach (strToArr($coupon['goods_category_ids']) as $id) {
                    $cateFilter[] = "cate_id1 = {$id} OR cate_id2 = {$id} OR cate_id3 = {$id}";
                }
                $filter[] = $cateFilter;
            }
            if ($coupon['goods_brand_ids']) {
                $brandFilter = [];
                foreach (strToArr($coupon['goods_brand_ids']) as $id) {
                    $brandFilter[] = "brand_id = {$id}";
                }
                $filter[] = $brandFilter;
            }
            if ($coupon['goods_tag_ids']) {
                $couponTagFilter = [];
                foreach (strToArr($coupon['goods_tag_ids']) as $item) {
                    $couponTagFilter[] = "tag_ids = {$item}";
                }
                $filter[] = $couponTagFilter;
            }
        } else {
            $ids = CouponGoods::where([
                'coupon_id' => $coupon_id
            ])
                ->column('goods_id');
            if ($ids) {
                $goodsFilter = [];
                foreach ($ids as $id) {
                    $goodsFilter[] = "id = {$id}";
                }
                $filter[] = $goodsFilter;
            }
        }

        return $filter;
    }
}